/*
 * @Description:
 * @Version:
 * @Author: Troubadour
 * @Date: 2023-11-13 09:30:45
 * @LastEditors: Troubadour
 * @LastEditTime: 2023-11-14 17:56:27
 */

#ifndef  __BSP_SDDRIVER_H__
#define  __BSP_SDDRIVER_H__

#include "main.h"

#define ENABLIE_HARD_SPI        (1)

#if ENABLIE_HARD_SPI
#include "spi.h"
#define SD_SPI_HANDLE           (hspi3)
#else
#define SD_SPI_MISO()           HAL_GPIO_ReadPin(SD_SPI_MISO_GPIO_Port, SD_SPI_MISO_Pin)
#define SD_SPI_MOSI(n)          HAL_GPIO_WritePin(SD_SPI_MOSI_GPIO_Port, SD_SPI_MOSI_Pin, (n) ? (GPIO_PIN_SET) : (GPIO_PIN_RESET))
#define SD_SPI_SCK(n)           HAL_GPIO_WritePin(SD_SPI_SCK_GPIO_Port, SD_SPI_SCK_Pin, (n) ? (GPIO_PIN_SET) : (GPIO_PIN_RESET))
#endif
#define SD_SPI_CS(n)            HAL_GPIO_WritePin(TF_CS_GPIO_Port, TF_CS_Pin, (n) ? (GPIO_PIN_SET) : (GPIO_PIN_RESET))
#define SD_Delay_Ms(ms)         HAL_Delay(ms)


/* SD卡类型 */
#define SDCard_TYPE_ERR 0x00
#define SDCard_TYPE_MMC 0x01
#define SDCard_TYPE_V1 0x02
#define SDCard_TYPE_V2 0x04
#define SDCard_TYPE_V2HC 0x06
#define CT_BLOCK  0x08    /* Block addressing */

/* SD卡命令 */
#define SDCard_CMD0 0 //卡复位
#define SDCard_CMD1 1
#define SDCard_CMD8 8 //命令8 ，SEND_IF_COND
#define SDCard_CMD9 9 //命令9 ，读CSD数据
#define SDCard_CMD10 10 // 命令10，读CID数据
#define SDCard_CMD12 12 //命令12，停止数据传输
#define SDCard_CMD16 16 //命令16，设置扇区大小 应返回0x00
#define SDCard_CMD17 17 //命令17，读扇区
#define SDCard_CMD18 18 //命令18，读多个扇区
#define SDCard_CMD23 23 //命令23，设置多扇区写入前预先擦除block
#define SDCard_CMD24 24 //命令24，写扇区
#define SDCard_CMD25 25 //命令25，写多个扇区
#define SDCard_CMD41 41 //命令41，应返回0x00
#define SDCard_CMD55 55 //命令55，应返回0x01
#define SDCard_CMD58 58 //命令58，读OCR信息
#define SDCard_CMD59 59 // 命令59，使能/禁止CRC，应返回0x00

/* SD卡扇区大小 */
#define SDCard_SECTOR_SIZE  (512)

enum _CD_HOLD
{
    HOLD = 0,
    RELEASE = 1,
};

typedef struct /* Card Specific Data */
{
    uint8_t CSDStruct;           /* CSD structure */
    uint8_t SysSpecVersion;      /* System specification version */
    uint8_t Reserved1;           /* Reserved */
    uint8_t TAAC;                /* Data read access-time 1 */
    uint8_t NSAC;                /* Data read access-time 2 in CLK cycles */
    uint8_t MaxBusClkFrec;       /* Max. bus clock frequency */
    uint16_t CardComdClasses;    /* Card command classes */
    uint8_t RdBlockLen;          /* Max. read data block length */
    uint8_t PartBlockRead;       /* Partial blocks for read allowed */
    uint8_t WrBlockMisalign;     /* Write block misalignment */
    uint8_t RdBlockMisalign;     /* Read block misalignment */
    uint8_t DSRImpl;             /* DSR implemented */
    uint8_t Reserved2;           /* Reserved */
    uint32_t DeviceSize;         /* Device Size */
    uint8_t MaxRdCurrentVDDMin;  /* Max. read current @ VDD min */
    uint8_t MaxRdCurrentVDDMax;  /* Max. read current @ VDD max */
    uint8_t MaxWrCurrentVDDMin;  /* Max. write current @ VDD min */
    uint8_t MaxWrCurrentVDDMax;  /* Max. write current @ VDD max */
    uint8_t DeviceSizeMul;       /* Device size multiplier */
    uint8_t EraseGrSize;         /* Erase group size */
    uint8_t EraseGrMul;          /* Erase group size multiplier */
    uint8_t WrProtectGrSize;     /* Write protect group size */
    uint8_t WrProtectGrEnable;   /* Write protect group enable */
    uint8_t ManDeflECC;          /* Manufacturer default ECC */
    uint8_t WrSpeedFact;         /* Write speed factor */
    uint8_t MaxWrBlockLen;       /* Max. write data block length */
    uint8_t WriteBlockPaPartial; /* Partial blocks for write allowed */
    uint8_t Reserved3;           /* Reserded */
    uint8_t ContentProtectAppli; /* Content protection application */
    uint8_t FileFormatGrouop;    /* File format group */
    uint8_t CopyFlag;            /* Copy flag (OTP) */
    uint8_t PermWrProtect;       /* Permanent write protection */
    uint8_t TempWrProtect;       /* Temporary write protection */
    uint8_t FileFormat;          /* File Format */
    uint8_t ECC;                 /* ECC code */
    uint8_t CSD_CRC;             /* CSD CRC */
    uint8_t Reserved4;           /* always 1*/
} MSD_CSD;

typedef struct /*Card Identification Data*/
{
    uint8_t ManufacturerID; /* ManufacturerID */
    uint16_t OEM_AppliID;   /* OEM/Application ID */
    uint32_t ProdName1;     /* Product Name part1 */
    uint8_t ProdName2;      /* Product Name part2*/
    uint8_t ProdRev;        /* Product Revision */
    uint32_t ProdSN;        /* Product Serial Number */
    uint8_t Reserved1;      /* Reserved1 */
    uint16_t ManufactDate;  /* Manufacturing Date */
    uint8_t CID_CRC;        /* CID CRC */
    uint8_t Reserved2;      /* always 1 */
} MSD_CID;

typedef struct
{
    MSD_CSD CSD;
    MSD_CID CID;
    uint32_t Capacity;  /* Card Capacity */
    uint32_t BlockSize; /* Card Block Size */
    uint16_t RCA;
    uint8_t CardType;
    uint32_t SpaceTotal; /* Total space size in file system */
    uint32_t SpaceFree;  /* Free space size in file system */
} MSD_CARDINFO, *PMSD_CARDINFO;

extern MSD_CARDINFO Bsp_SDCardInfo;

HAL_StatusTypeDef Bsp_SD_Init(void);
HAL_StatusTypeDef Bsp_SD_GETCID(uint8_t *cid_data);
HAL_StatusTypeDef Bsp_SD_GetCardInfo(PMSD_CARDINFO SD0_CardInfo);
HAL_StatusTypeDef Bsp_SD_WriteDisk(uint8_t *buf, uint32_t sector, uint32_t cnt);
HAL_StatusTypeDef Bsp_SD_ReadDisk(uint8_t *buf, uint32_t sector, uint32_t cnt);


#endif  /* __BSP_SDDRIVER_H__ */
